#include "VxIrrLib.h"

//============================================================================
//=== constructor ===//
EntMgr::EntMgr()
	: m_s32NextEntId(1)
	, m_poIrrBase(0)
{
	// empty
}
//============================================================================
//=== destructor ===//
EntMgr::~EntMgr()
{
}

//============================================================================
//! startup
RCODE EntMgr::Startup( VxIrrBase * poIrrBase )
{
	m_poIrrBase = poIrrBase;
	m_s32NextEntId = 1;
	return 0;
}
//============================================================================
//! shutdown
void EntMgr::Shutdown( void )
{
	ClearEnts();
}
//============================================================================

//============================================================================
//=== methods ===//
void EntMgr::Update( U32 u32FrameTimeMs )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator ) 
	{
		EntBase * poEnt = *Iterator;
		poEnt->Update( u32FrameTimeMs );
	}
}
//============================================================================
//! called once per second
void EntMgr::OncePerSecond( void )
{
	if( m_poIrrBase->m_iGameInstance > 1 )
	{
		log_msg( 0, "EntMgr::OncePerSecond: start\n");
	}
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		(*Iterator)->OncePerSecond();
	}
	if( m_poIrrBase->m_iGameInstance > 1 )
	{
		log_msg( 0, "EntMgr::OncePerSecond: done\n");
	}
}

//============================================================================
//! interpolate between positions
void EntMgr::InterpolatePositions( F32 f32BlendFactor )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		EntBase * poEnt = *Iterator;
		poEnt->CalculateInterpolatedPosition( f32BlendFactor );
		poEnt->UpdateRender();
	}
}
//============================================================================
//! frame is about to be rendered
void EntMgr::BeginFrame( void )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		EntBase * poEnt = *Iterator;
		poEnt->BeginFrame();
	}
}
//============================================================================
//! frame has been rendered
void EntMgr::EndFrame( void )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		EntBase * poEnt = *Iterator;
		poEnt->EndFrame();
	}
	// now remove any enities marked for deletion
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ) 
	{
		EntBase * poEnt = *Iterator;
		// check if needs deleted
		if( poEnt->GetDeleted() ) 
		{
			// do any before delete stuff here

			// do we need a shutdown??
			log_msg( 0, "EntMgr::EndFrame: deleting entity %s\n", poEnt->m_strEntProperName.c_str() );
			delete poEnt;
			Iterator = m_lstEntities.erase(Iterator);
		}
		else 
		{
			++Iterator;
		}
	}
}
//============================================================================
//! add entity to list of entities
EntBase * EntMgr::AddEnt( EntBase * poEnt )
{
	if( NULL != poEnt ) 
	{
		poEnt->SetEntId( m_s32NextEntId );
		m_s32NextEntId++;
		m_lstEntities.push_back( poEnt );
	}
	else
	{
		log_msg( 0, "EntMgr::AddEnt: NULL ENTITY\n" );
	}
	return poEnt;
}
//============================================================================
//! remove entity from list of entities
void EntMgr::DeleteEnt( EntBase * poEnt )
{
	poEnt->SetDeleted(true);
}
//============================================================================
//! remove entity from list of entities
void EntMgr::DeleteEntById( S32 s32Id )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		if( (*Iterator)->GetEntId() == s32Id ) 
		{
			delete (*Iterator);
			m_lstEntities.erase(Iterator);
			return;
		}
	}
}
//============================================================================
//! find entity by name
EntBase * EntMgr::GetEntByCommonName( const irr::core::stringc& strName )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		if((*Iterator)->GetCommonName() == strName)
		{
			return *Iterator;
		}
	}
	return NULL;
}
//============================================================================
//! find entity by name
EntBase * EntMgr::GetEntByProperName( const irr::core::stringc& strName )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		if((*Iterator)->GetProperName() == strName)
		{
			return *Iterator;
		}
	}
	return NULL;
}
//============================================================================
//! find entity by Id
EntBase * EntMgr::GetEntById( S32 s32Id )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		if((*Iterator)->GetEntId() == s32Id )
		{
			return *Iterator;
		}
	}
	return NULL;
}
//============================================================================
//! find entity by type ( returns first match found )
EntBase * EntMgr::GetEntByType( int iType )
{
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator) 
	{
		if( (*Iterator)->GetEntType() == iType )
		{
			return *Iterator;
		}
	}
	return NULL;
}
//============================================================================

//! clear all entities form list
void EntMgr::ClearEnts( void )
{
	// delete constraints first
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end();) 
	{
		EntBase * poEnt = *Iterator;
		if(	( eEntityTypeConstraintHinge == poEnt->GetEntType() ) || 
			( eEntityTypeConstraintD6 == poEnt->GetEntType() ) )
		{
			delete poEnt;
			poEnt = NULL;
			Iterator = m_lstEntities.erase(Iterator);
		}
		else
		{
			++Iterator;
		}
	}

	// delete entities
	for(irr::core::list<EntBase *>::Iterator Iterator = m_lstEntities.begin(); Iterator != m_lstEntities.end(); ++Iterator)
	{
		delete (*Iterator);
	}

	m_lstEntities.clear();
	m_s32NextEntId = 1;
}
//============================================================================

